iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Kubernetes

Think Again Kubernetes系列 第 22

初探 Eviction 以及深入 API-initiated Eviction

  • 分享至 

  • xImage
  •  

什麼是驅逐?

驅逐是指 Kubernetes 從叢集中移除正在執行的 Pod 的過程。這可以透過 API 主動進行,也可以由 kubelet 作為對節點壓力做出反應而自動進行。

在 Kubernetes 中主要有兩種類型來驅逐 Pod:

  • API-initiated Eviction: 您可以使用 Eviction API 來觸發 Pod 的驅逐,這會走入 Graceful Termination。藉由 API Object 觸發的驅逐都屬於這類型,例如 HPA 以及 Deploy,還有常見於 Kubernetes 升級時候的 kubectl drain。

  • Node-Pressure Eviction: 當 Node 上的資源,例如記憶體、磁碟空間或檔案系統 inode,消耗到特定級別時,kubelet 會主動終止 Pod 以回收資源。這個行為被稱為 Node-Pressure Eviction

What is API-initiated Eviction?

當你用 Eviction API 來觸發 Pod 的驅逐,這會走入 Graceful Termination。藉由 API Object 觸發的驅逐都屬於這類型,例如 HPA 以及 Deploy,還有常見於 Kubernetes 升級時候的 kubectl drain。
API-initiated Eviction 會遵守 PodDisruptionBudget 和 terminationGracePeriodSeconds。

當請求 API-initiated Eviction,API Server 會執行檢查,並以以下其中一種 HTTP states 回應:

  • 200 OK:允許 Eviction 並建立 Eviction subresource,並刪除 Pod。

  • 429 Too Many Requests

    • 由於設定的 PodDisruptionBudget,目前不允許驅逐。 您可以稍後再嘗試驅逐。

    • 由於 API 速率限制,可能會看到此回應。

  • 500 Internal Server Error:不允許驅逐,因為設定錯誤,例如多個 PodDisruptionBudget 參考同一個 Pod。

如果要驅逐的 Pod 不屬於 PodDisruptionBudget,則 API Server 一律會傳回 200 OK 並允許驅逐。

如果 API Server 允許驅逐,則 Pod 會按以下步驟刪除:

  1. API Server 中的 Pod 會被打上 delete timestamp,之後 API Server 會將 Pod 視為已終止。 Pod 也會標記為設定的 Grace Period。

  2. 執行本機 Pod 的節點上的 kubelet 會注意到 Pod 已標記為終止,並開始 Gracefully Shutdown 本機 Pod。

  3. 當 kubelet 關閉 Pod 時,Control 會從 Endpoint 以及 EndpointSlice 中移除 Pod。 因此,Controller 不再將 Pod 視為有效物件。

  4. Pod 的 Grace Period 到期後,kubelet 會 forcefully terminates Pod。

  5. kubelet 告知 API Server 已刪除 Pod。

  6. API Server 會刪除 Pod。

用 HTTP Request 觸發 API-initiated Eviction

先用 kubectl proxy 把 api-server 暴露出來

kubectl proxy

呼叫 Pod resources 中的 subresources

#!/bin/bash

# Define variables for the pod name and namespace
# REMINDER: Replace the pod name as you want
pod_name="nginx-77b4fdf86c-vfqbc"
namespace="default"

# Create the eviction payload as a JSON object
eviction_payload=$(cat <<EOF
{
  "apiVersion": "policy/v1",
  "kind": "Eviction",
  "metadata": {
    "name": "${pod_name}",
    "namespace": "${namespace}"
  }
}
EOF
)

# Send the eviction request using curl
curl -X POST \
     -H "Content-Type: application/json" \
     -d "${eviction_payload}" \
     http://localhost:8001/api/v1/namespaces/${namespace}/pods/${pod_name}/eviction

Preemption 是 API-initiated Eviction 嗎?

不是,Preemption 是直接用 HTTP method Delete Pod,而不是呼叫 Eviction Subresource
文件沒說,所以請看 code

https://github.com/kubernetes/kubernetes/blob/f6a11da279877be45048cafe92a6027fcf91cfe5/pkg/scheduler/framework/preemption/preemption.go#L378

由於傳入的 delelteoptions 是空的,所以吃 pod.spec 裡面的 terminationGracePeriodSeconds

關於 PDB,前面有提到,Preemption 會尊重,但不保證遵守。


由於 Node-Pressure Eviction 行為跟 API-initiated Eviction 完全不同,又牽扯到 QoS 以及 Eviction thresholds,所以下一章單獨講。


上一篇
利用 kube-scheduler-simulator 測試 Preemption
下一篇
Node Pressure Eviction
系列文
Think Again Kubernetes31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言